package com.calendar.MaiDong;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.TextUtils;

import com.calendar.MaiDong.entity.NDate;
import com.calendar.MaiDong.painter.CalendarPainter;
import com.calendar.MaiDong.utils.Util;

import org.joda.time.LocalDate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class CustomPainter implements CalendarPainter {

    private Paint circlePaint;
    private Paint textPaint;
    private Context context;
    private int noAlphaColor = 255;

    protected List<LocalDate> mHolidayList;
    protected List<LocalDate> mWorkdayList;

    private List<LocalDate> mPointList;
    private Map<LocalDate, String> mReplaceLunarStrMap;
    private Map<LocalDate, Integer> mReplaceLunarColorMap;

    //    颜色都为16进制
//    当天的颜色
    private String todayColor;
    //    选中的颜色
    private String selectionColor;
    //    含有事件的日期默认颜色
    private String eventDefaultColor;
    //    星期几的颜色
    private String weekdayTextColor;
    //    头部标题颜色
    private String headerTitleColor;
    //    日历背景颜色
    private String calendarBackgroundColor;
    //    标题默认颜色
    private String titleDefaultColor;
    //    事件图片
    private String imageString;
    //    是否显示阴历
    private boolean showLunar;
    //    是否是中文
    private boolean chinese;
    //    是否显示事件
    private boolean showEvent;
    //    是否多选
    private boolean allowsMultipleSelection;
    //    是否显示正方形
    private boolean square;
//    是否显示节假日
    private boolean showHoliday;

    public void setTodayColor(String todayColor) {
        this.todayColor = todayColor;
    }

    public void setSelectionColor(String selectionColor) {
        this.selectionColor = selectionColor;
    }

    public void setEventDefaultColor(String eventDefaultColor) {
        this.eventDefaultColor = eventDefaultColor;
    }

    public void setWeekdayTextColor(String weekdayTextColor) {
        this.weekdayTextColor = weekdayTextColor;
    }

    public void setHeaderTitleColor(String headerTitleColor) {
        this.headerTitleColor = headerTitleColor;
    }

    public void setCalendarBackgroundColor(String calendarBackgroundColor) {
        this.calendarBackgroundColor = calendarBackgroundColor;
    }

    public void setTitleDefaultColor(String titleDefaultColor) {
        this.titleDefaultColor = titleDefaultColor;
    }

    public void setImageString(String imageString) {
        this.imageString = imageString;
    }

    public void setShowLunar(boolean showLunar) {
        this.showLunar = showLunar;
    }

    public void setChinese(boolean chinese) {
        this.chinese = chinese;
    }

    public void setShowEvent(boolean showEvent) {
        this.showEvent = showEvent;
    }

    public void setAllowsMultipleSelection(boolean allowsMultipleSelection) {
        this.allowsMultipleSelection = allowsMultipleSelection;
    }

    public void setSquare(boolean square) {
        this.square = square;
    }

    public void setShowHoliday(boolean showHoliday) {
        this.showHoliday = showHoliday;
    }

    public CustomPainter(Context context) {
        this.context = context;
        circlePaint = getPaint();
        textPaint = getPaint();
        mPointList = new ArrayList<>();
        mHolidayList = new ArrayList<>();
        mWorkdayList = new ArrayList<>();
        mReplaceLunarStrMap = new HashMap<>();
        mReplaceLunarColorMap = new HashMap<>();

        List<String> holidayList = Util.getHolidayList();
        for (int i = 0; i < holidayList.size(); i++) {
            mHolidayList.add(new LocalDate(holidayList.get(i)));
        }
        List<String> workdayList = Util.getWorkdayList();
        for (int i = 0; i < workdayList.size(); i++) {
            mWorkdayList.add(new LocalDate(workdayList.get(i)));
        }
    }

    private Paint getPaint(){
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTextAlign(Paint.Align.CENTER);
        return paint;
    }

    @Override
    public void onDrawToday(Canvas canvas, Rect rect, NDate nDate, boolean isSelect) {
        if (isSelect) {
            drawSolidCircle(canvas,rect);
            drawTodaySolar(canvas, rect, true, nDate.localDate);
            drawTodayLunar(canvas,rect,true,noAlphaColor,nDate);
            drawPoint(canvas, rect, true, noAlphaColor, nDate.localDate);
            drawHolidays(canvas, rect, true, noAlphaColor, nDate.localDate);
        } else {
            drawTodayUnselcetCircle(canvas,rect);
            drawTodaySolar(canvas, rect, false, nDate.localDate);
            drawTodayLunar(canvas,rect,true,noAlphaColor,nDate);
            drawPoint(canvas, rect, false, noAlphaColor, nDate.localDate);
            drawHolidays(canvas, rect, false, noAlphaColor, nDate.localDate);
        }
    }

    @Override
    public void onDrawDisableDate(Canvas canvas, Rect rect, NDate nDate) {
        drawOtherSolar(canvas, rect, false,90, nDate.localDate);
        drawTodayLunar(canvas,rect,true,90,nDate);
        drawOtherdayLunar(canvas,rect,false,90,nDate);
        drawPoint(canvas, rect, false, 90, nDate.localDate);
        drawHolidays(canvas, rect, false, noAlphaColor, nDate.localDate);
    }

    @Override
    public void onDrawCurrentMonthOrWeek(Canvas canvas, Rect rect, NDate nDate, boolean isSelect) {
        if (isSelect) {
            drawHollowCircle(canvas,rect);
            drawOtherSolar(canvas, rect, true,255, nDate.localDate);
            drawOtherdayLunar(canvas,rect,true,noAlphaColor,nDate);
            drawPoint(canvas, rect, false, noAlphaColor, nDate.localDate);
            drawHolidays(canvas, rect, true, noAlphaColor, nDate.localDate);
        } else {
            drawOtherSolar(canvas, rect, false,255, nDate.localDate);
            drawOtherdayLunar(canvas,rect,false,noAlphaColor,nDate);
            drawPoint(canvas, rect, false, noAlphaColor, nDate.localDate);
            drawHolidays(canvas, rect, false, noAlphaColor, nDate.localDate);
        }
    }

    @Override
    public void onDrawNotCurrentMonth(Canvas canvas, Rect rect, NDate nDate) {
    }

//    空心圆
    public void drawHollowCircle(Canvas canvas,Rect rect){
        circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);
        circlePaint.setStrokeWidth(Util.dp2px(context, 1));
        circlePaint.setColor(Color.parseColor(selectionColor));
        circlePaint.setAlpha(255);
        canvas.drawCircle(rect.centerX(), rect.centerY(), Util.dp2px(context, 22), circlePaint);
    }

    //实心圆
    private void drawSolidCircle(Canvas canvas, Rect rect) {
        circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);
        circlePaint.setStrokeWidth(Util.dp2px(context, 1));
        circlePaint.setColor(Color.parseColor(selectionColor));
        circlePaint.setAlpha(255);
        canvas.drawCircle(rect.centerX(), rect.centerY(), Util.dp2px(context, 22), circlePaint);
    }

    //今天没有选中的时候
    private void drawTodayUnselcetCircle(Canvas canvas, Rect rect) {
        circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);
        circlePaint.setStrokeWidth(Util.dp2px(context, 1));
        circlePaint.setColor(Color.parseColor(todayColor));
        circlePaint.setAlpha(255);
        canvas.drawCircle(rect.centerX(), rect.centerY(), Util.dp2px(context, 22), circlePaint);
    }

    //今天的公历
    private void drawTodaySolar(Canvas canvas, Rect rect, boolean isSelect, LocalDate date) {
        textPaint.setColor(Color.WHITE);
        textPaint.setAlpha(255);
        textPaint.setTextSize(Util.sp2px(context, 18));
        canvas.drawText(date.getDayOfMonth() + "", rect.centerX(), showLunar ? rect.centerY() : getBaseLineY(rect), textPaint);
    }

    //其他的公历
    private void drawOtherSolar(Canvas canvas, Rect rect,boolean isSelect, int alphaColor, LocalDate date) {
        if(isSelect){
            textPaint.setColor(Color.WHITE);
        }
        else {
            textPaint.setColor(Color.BLACK);
        }
        textPaint.setAlpha(alphaColor);
        textPaint.setTextSize(Util.sp2px(context, 18));
        canvas.drawText(date.getDayOfMonth() + "", rect.centerX(), showLunar ? rect.centerY() : getBaseLineY(rect), textPaint);
    }

    //绘制圆点
    private void drawPoint(Canvas canvas, Rect rect, boolean isTodaySelect, int alphaColor, LocalDate date) {
        if (mPointList != null && mPointList.contains(date)) {
            circlePaint.setStyle(Paint.Style.FILL);
            circlePaint.setColor(isTodaySelect ? Color.WHITE : Color.parseColor(eventDefaultColor));
            circlePaint.setAlpha(alphaColor);
            canvas.drawCircle(rect.centerX(), rect.centerY() + Util.dp2px(context, 18)+20, Util.dp2px(context, 3), circlePaint);
        }
    }

    //今天的农历
    private void drawTodayLunar(Canvas canvas, Rect rec, boolean isSelect, int alphaColor, NDate nDate){
        if(showLunar){
            String lunarString = mReplaceLunarStrMap.get(nDate.localDate);
            if(lunarString == null){
                if (!TextUtils.isEmpty(nDate.lunarHoliday)) {
                    textPaint.setColor(Color.WHITE);
                    lunarString = nDate.lunarHoliday;
                } else if (!TextUtils.isEmpty(nDate.solarTerm)) {
                    textPaint.setColor(Color.WHITE);
                    lunarString = nDate.solarTerm;
                } else if (!TextUtils.isEmpty(nDate.solarHoliday)) {
                    textPaint.setColor(Color.WHITE);
                    lunarString = nDate.solarHoliday;
                } else {
                    textPaint.setColor(Color.WHITE);
                    lunarString = nDate.lunar.lunarDrawStr;
                }
            }
            else {
                Integer color = mReplaceLunarColorMap.get(nDate.localDate);
                if (color == null) {
                    textPaint.setColor(Color.GRAY);
                } else {
                    textPaint.setColor(Color.WHITE);
                }
            }
            textPaint.setTextSize(Util.sp2px(context, 10));
            textPaint.setAlpha(alphaColor);
            canvas.drawText(lunarString, rec.centerX(), rec.centerY() + Util.sp2px(context, 15), textPaint);
        }
    }

    //其他的农历
    private void drawOtherdayLunar(Canvas canvas, Rect rec, boolean isSelect, int alphaColor, NDate nDate){
        if(showLunar){
            String lunarString = mReplaceLunarStrMap.get(nDate.localDate);
            if (lunarString == null) {
                if (!TextUtils.isEmpty(nDate.lunarHoliday)) {
                    textPaint.setColor(isSelect ? Color.WHITE : Color.GRAY);
                    lunarString = nDate.lunarHoliday;
                } else if (!TextUtils.isEmpty(nDate.solarTerm)) {
                    textPaint.setColor(isSelect ? Color.WHITE : Color.GRAY);
                    lunarString = nDate.solarTerm;
                } else if (!TextUtils.isEmpty(nDate.solarHoliday)) {
                    textPaint.setColor(isSelect ? Color.WHITE : Color.GRAY);
                    lunarString = nDate.solarHoliday;
                } else {
                    textPaint.setColor(isSelect ? Color.WHITE : Color.GRAY);
                    lunarString = nDate.lunar.lunarDrawStr;
                }
            }
            else {
                Integer color = mReplaceLunarColorMap.get(nDate.localDate);
                if (color == null) {
                    textPaint.setColor(Color.GRAY);
                } else {
                    textPaint.setColor(isSelect ? Color.WHITE : Color.GRAY);
                }
            }
            textPaint.setTextSize(Util.sp2px(context, 10));
            textPaint.setAlpha(alphaColor);
            canvas.drawText(lunarString, rec.centerX(), rec.centerY() + Util.sp2px(context, 15), textPaint);
        }
    }

    //绘制节假日
    private void drawHolidays(Canvas canvas, Rect rect, boolean isTodaySelect, int alphaColor, LocalDate date) {
        if (showHoliday) {
            int[] holidayLocation = getHolidayLocation(rect.centerX(), rect.centerY());
            textPaint.setTextSize(Util.sp2px(context, 10));
            if (mHolidayList.contains(date)) {
                textPaint.setColor(Color.parseColor(todayColor));
                textPaint.setAlpha(alphaColor);
                canvas.drawText("休", holidayLocation[0], holidayLocation[1], textPaint);
            } else if (mWorkdayList.contains(date)) {
                textPaint.setColor(Color.parseColor(todayColor));
                textPaint.setAlpha(alphaColor);
                canvas.drawText("班", holidayLocation[0], holidayLocation[1], textPaint);
            }
        }
    }

    //Holiday的位置
    private int[] getHolidayLocation(int centerX, int centerY) {
        int[] location = new int[2];
        int solarTexyCenterY = getSolarTextCenterY(centerY);
        location[0] = (int) (centerX + Util.sp2px(context, 15));
        location[1] = solarTexyCenterY;
        return location;
    }


    //公历文字的竖直中心y
    private int getSolarTextCenterY(int centerY) {
        textPaint.setTextSize(Util.sp2px(context, 18));
        Paint.FontMetricsInt fontMetricsInt = textPaint.getFontMetricsInt();
        int ascent = fontMetricsInt.ascent;
        int descent = fontMetricsInt.descent;
        int textCenterY = descent / 2 + centerY + ascent / 2;//文字的中心y
        return textCenterY;
    }

//    设置标记
    public void setPointList(List<String> list) {
        List<LocalDate> localDates = new ArrayList<>();
        for(int i = 0 ; i < list.size() ; i++){
            try {
                localDates.add(new LocalDate(list.get(i)));
            }catch (Exception e){
                throw new RuntimeException("setPointList的参数需要 yyyy-MM-dd 格式的日期");
            }
        }
        mPointList.clear();
        mPointList.addAll(localDates);
    }

    //设置替换农历的文字
    public void setReplaceLunarStrMap(Map<String, String> replaceLunarStrMap) {
        Map<LocalDate, String> map = new HashMap<>();
        for (String key : replaceLunarStrMap.keySet()) {
            try {
                map.put(new LocalDate(key), replaceLunarStrMap.get(key));
            } catch (Exception e) {
                throw new RuntimeException("setReplaceLunarStrMap的参数需要 yyyy-MM-dd 格式的日期");
            }
        }
        mReplaceLunarStrMap.clear();
        mReplaceLunarStrMap.putAll(map);
    }

    private int getBaseLineY(Rect rect) {
        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
        float top = fontMetrics.top;
        float bottom = fontMetrics.bottom;
        int baseLineY = (int) (rect.centerY() - top / 2 - bottom / 2);
        return baseLineY;
    }

    private Rect getNewRect(Context context,Rect rect) {
        int rectDistance = (int) Util.dp2px(context, 20);
        return new Rect(rect.centerX() - rectDistance, rect.centerY() - rectDistance, rect.centerX() + rectDistance, rect.centerY() + rectDistance);
    }
}
